import {host, getQuery, isUndefined, isEmptyString, stringToDate, setCookie, getCookie, removeCookie} from '../util'
import fetch from 'isomorphic-fetch'

export default {
    defaultParams: {
        client_id: '',
        client_secret: '',
        auth_svr: 'https://pas.mingyuanyun.com/auth',
        token_svr: 'https://pas.mingyuanyun.com/token',
        refresh_svr: 'https://pas.mingyuanyun.com/refresh',
        user_info_svr: 'https://pas.mingyuanyun.com/user-info',
        logout_svr: 'https://pas.mingyuanyun.com/logout',
        local_mode: 'localStorage',
        cookie_duration: 129600,
        cookie_domain: '.mingyuanyun.com'
    },

    invalidLogonIdentity: {
        name: 'InvalidLogonIdentityException',
        code: 100110,
        message: '未能检测到有效的登录身份，请重新登录'
    },

    tokenRefreshing: false,

    /* 获取用户信息 过程 ================================================================================================ */
    userInfo(access_token, success, error) {
        fetch(
            `${this.defaultParams.user_info_svr}/${access_token}`,
            {
                method: 'GET',
            }).then((res) => {
            res.json().then((json) => {
                if (json.result) {
                    this.saveLogonUser(json.userData);
                    success();
                } else {
                    error(json.userData);
                }
            });
        });
    },
    /**
     * 将拉取到登录用户的 user info 保存在 localStorage 中
     * @param user
     */
    saveLogonUser(user) {
        if(this.defaultParams.local_mode == 'cookie') {
            setCookie('__myt_auth_user',
                JSON.stringify(user),
                this.defaultParams.cookie_duration,
                __DEV__ ? undefined : this.defaultParams.cookie_domain);
        } else if(this.defaultParams.local_mode == 'sessionStorage') {
            sessionStorage.logonUser = JSON.stringify(user);
        } else {
            localStorage.logonUser = JSON.stringify(user);
        }
    },

    /**
     * 获取 localStorage 中保存的 user info
     * @returns mixed
     */
    getLogonUser() {
        try {
            const logonUser = (this.defaultParams.local_mode == 'cookie' ? getCookie('__myt_auth_user') :
                (this.defaultParams.local_mode == 'sessionStorage' ? sessionStorage.logonUser : localStorage.logonUser));
            return logonUser === undefined ? undefined : JSON.parse(logonUser);
        } catch (e) {
            return undefined;
        }
    },

    checkLogon(location, replace) {
        const userInfo = this.getLogonUser();
        const tokens = this.getTokens();
        if (userInfo === undefined || tokens === undefined || isEmptyString(tokens.access_token)) {
            this.saveRedirectUrl(location);
            replace('/__oauth2/auth');
        }
    },

    /**
     * 从 localStorage 中删除保存的 user info
     */
    clearLogonUser(){
        if(this.defaultParams.local_mode == 'cookie') {
            removeCookie('__myt_auth_user');
        } else if(this.defaultParams.local_mode == 'sessionStorage') {
            delete sessionStorage.logonUser;
        } else {
            delete localStorage.logonUser;
        }
    },

    /**
     * 登出
     */
    logout(location) {
        this.saveRedirectUrl(location);
        // 清除EKP登录记录
        removeCookie('Email_User');
        removeCookie('Login_User');
        const doLogoutUrl = `${host()}__oauth2/logout`;
        window.location.href = `${this.defaultParams.logout_svr}?redirect_uri=${encodeURIComponent(doLogoutUrl)}`;
    },
    /**
     * 执行登出
     * @param replace
     */
    doLogout(replace) {
        this.clearLogonUser();
        this.clearTokens();
        this.returnToRedirectUrl(replace);
    },

    /**
     * 保存回调页面地址
     */
    saveRedirectUrl(location) {
        let {pathname, search} = location;
        if (pathname.length > 1 && pathname.substr(0, 1) == '/') pathname = pathname.substr(1);
        search = search || '';
        const returnPath = `${pathname}${search}`;
        localStorage.auth_return_url = (returnPath == '/' ? '/' : `/${returnPath}`);
    },

    returnToRedirectUrl(replace) {
        replace(isEmptyString(localStorage.auth_return_url) ? '/' : localStorage.auth_return_url);
    },

    /* 处理身份缓存 ===================================================================================================== */
    /**
     * 将申请或刷新得到的tokens保存在 localStorage 中
     * @param tokens
     */
    saveTokens(tokens) {
        tokens.updated = new Date();
        if(this.defaultParams.local_mode == 'cookie') {
            setCookie('__myt_auth_token',
                JSON.stringify(tokens),
                this.defaultParams.cookie_duration,
                __DEV__ ? undefined : this.defaultParams.cookie_domain);
        } else if(this.defaultParams.local_mode == 'sessionStorage') {
            sessionStorage.tokens = JSON.stringify(tokens);
        } else {
            localStorage.tokens = JSON.stringify(tokens);
        }

    },

    /**
     * 获取 localStorage 中保存的 tokens
     * @returns mixed
     */
    getTokens() {
        try {
            const tokens = (this.defaultParams.local_mode == 'cookie' ? getCookie('__myt_auth_token') :
                (this.defaultParams.local_mode == 'sessionStorage' ? sessionStorage.tokens : localStorage.tokens));
            return tokens === undefined ? undefined : JSON.parse(tokens);
        } catch (e) {
            return undefined;
        }
    },

    /**
     * 从 localStorage 中删除保存的 tokens
     */
    clearTokens(){
        if(this.defaultParams.local_mode == 'cookie') {
            removeCookie('__myt_auth_token');
        } else if(this.defaultParams.local_mode == 'sessionStorage') {
            delete sessionStorage.tokens;
        } else {
            delete localStorage.tokens;
        }
    },

    isTokenValid(tokens) {
        if (isUndefined(tokens)) return false;
        if (isEmptyString(tokens.access_token) || isUndefined(tokens.expires_in) || isUndefined(tokens.updated)) return false;
        // 检查 accessToken 是否还在有效期
        try {
            let ms = (new Date()).getTime() - stringToDate(tokens.updated).getTime();
            return (ms <= ((tokens.expires_in - 10) * 1000));
        } catch (e) {
            return false;
        }
    },

    /* 申请 Token 过程 ================================================================================================= */


    /**
     * 解析授权成功后的授权码回调
     * @returns {{result: boolean, code: (String|Object)}}
     */
    resolveAuthCallback() {
        let result = this.checkClientState();
        this.clearClientState();
        return {
            result: result,
            code: getQuery('code'),
            error: result ? undefined : {
                    name: 'ClientStateExpiredException',
                    code: 100111,
                    message: '客户端状态已失效，请重新登录'
                }
        }
    },

    /**
     * 获取token
     * @param code
     * @param success
     * @param error
     */
    token(code, success, error) {
        fetch(
            this.defaultParams.token_svr,
            {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: `grant_type=authorization_code&client_id=${this.defaultParams.client_id}&client_secret=${this.defaultParams.client_secret}&code=${code}&redirect_uri=${this.getRedirectUrl()}`,
            }).then((res) => {
            res.json().then((json) => {
                if (json.result) {
                    let tokens = json.userData;
                    // 保存token
                    this.saveTokens(tokens);
                    success(tokens.access_token);
                } else {
                    error(json.userData);
                }
            });
        });
    },

    waitTokenRefreshed(next) {
        setTimeout(() => {
            if(this.tokenRefreshing) {
                this.waitTokenRefreshed(next);
            } else {
                next();
            }
        }, 500);
    },


    prepareRefresh(refresh, next) {
        if (this.tokenRefreshing) {
            // 等待
            this.waitTokenRefreshed(next);
        } else {
            this.tokenRefreshing = true;
            refresh();
        }
    },

    /**
     * 刷新token
     * @param success
     * @param error
     */
    refresh(success, error) {
        const tokens = this.getTokens();
        if (tokens === undefined)
            error(this.invalidLogonIdentity);
        fetch(
            this.defaultParams.refresh_svr,
            {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: `client_id=${this.defaultParams.client_id}&code=${tokens.refresh_token}`,
            }).then((res) => {
            res.json().then((json) => {
                if (json.result) {
                    let tokens = json.userData;
                    // 保存token
                    this.saveTokens(tokens);
                    this.tokenRefreshing = false;
                    success(tokens.access_token);
                } else {
                    this.tokenRefreshing = false;
                    error(json.userData);
                }
            });
        });
    },


    /* 申请 AuthorizationCode 过程 ===================================================================================== */
    /**
     * 重新认证
     */
    reAuth() {
        this.clearLogonUser();
        this.clearTokens();
        this.redirectToAuthUrl();
    },
    /**
     * 跳转到授权站点
     */
    redirectToAuthUrl() {
        const clientState = this.generateOAuthClientState(6);
        const {auth_svr, client_id} = this.defaultParams;
        window.location.href = auth_svr + '?response_type=code&client_id=' + client_id +
            '&scope=' + '' +
            '&state=' + clientState +
            '&redirect_uri=' + encodeURIComponent(this.getRedirectUrl());
    },


    /* 公共方法 ======================================================================================================== */

    /**
     * 获取auth成功之后的跳转地址
     */
    getRedirectUrl(){
        return host() + '__oauth2/callback';
    },


    /**
     * 生成客户端随机码
     * @param n
     * @returns {string}
     */
    generateOAuthClientState(n) {
        const chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
        let res = "";
        for (let i = 0; i < n; i++) {
            let id = Math.ceil(Math.random() * 35);
            res += chars[id];
        }
        localStorage.oauthState = res;
        return res;
    },

    /**
     * 检查客户端随机码
     * @returns {boolean}
     */
    checkClientState() {
        let state = getQuery('state');
        return !(isEmptyString(localStorage.oauthState) || (state != localStorage.oauthState));
    },

    /**
     * 清除客户端随机码
     */
    clearClientState() {
        delete localStorage.oauthState;
    },
}
